package org.ruiyichen.guizhou.agr.net;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

import org.ruiyichen.guizhou.agr.base.BaseActivity;
import org.ruiyichen.guizhou.agr.config.Constant;
import org.ruiyichen.guizhou.agr.net.okhttp.OkHttpUtils;
import org.ruiyichen.guizhou.agr.net.okhttp.builder.PostFormBuilder;
import org.ruiyichen.guizhou.agr.net.okhttp.callback.Callback;
import org.ruiyichen.guizhou.agr.net.okhttp.callback.FileCallBack;
import org.ruiyichen.guizhou.agr.utils.ACache;
import org.ruiyichen.guizhou.agr.utils.FileUtils;
import org.ruiyichen.guizhou.agr.utils.L;
import org.ruiyichen.guizhou.agr.utils.NetWorkUtils;
import org.ruiyichen.guizhou.agr.utils.StrUtil;

import com.google.gson.Gson;

import java.io.File;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import okhttp3.Call;
import okhttp3.Response;

/**
 * 作者：Administrator
 * 邮箱：wutian8489@foxmail.com
 */
public class OkHttpManager {
    /**
     * 请求时间
     */
    private static int TIMES = 30;
    private Handler mHandler;
    private Context mContext;

    private ACache mACache;


    public OkHttpManager(Context context, Handler bHandler) {
        this.mContext = context;
        this.mHandler = bHandler;
        mACache = ACache.get(mContext);
//        mOkHttpClient = new OkHttpClient();
        // 获取UI主线程
//        mDelivery = new Handler(Looper.getMainLooper());
    }

    /**
     * 初始化上下文
     * <p/>
     * //     * @param context
     *
     * @return
     */
//    public OkHttpManager initManager(Context context,Handler bHandler) {
//
//        //        //设置缓存路径
////        File httpCacheDirectory = new File(mContext.getCacheDir(), "responses");
////        L.e("File:" + httpCacheDirectory.getAbsolutePath());
////        //设置缓存 10M
////        Cache cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
////        //缓存
////        mOkHttpClient = new OkHttpClient.Builder().cache(cache)./*addInterceptor(interceptor).*/build();
//        return this;
//    }

    public interface HttpCallback {
        /**
         * @param result 回调参数
         * @param code   回调标记位
         */
        void onSuccess(String result, int code);

        /**
         * @param code 回调标记位
         */
        void onStart(int code);

        /**
         * @param code 回调标记位
         */
        void onFailure(int code);

    }


    private static int lastRequestType = -1;
    private static String lastRequestParams;


    /**
     * 发送网络请求
     *
     * @param requestType   请求标示
     * @param body          请求报文
     * @param hasCache      是否需要缓存
     * @param responseType  返回报文对应解析
     * @param isShowLoading 是否显示等等待
     * @param isZip         是否压缩
     */
    public boolean httpRequest(final int requestType, int isPost, final Map body, final boolean
            hasCache, final Type responseType, boolean isShowLoading, boolean isZip) {
//        L.e(requestType + "请求参数:" + body.toString());
        // 如果发相同的请求且相隔时间太短则不响应后面的请求
        if (NetWorkUtils.isMostPost() && lastRequestType == requestType && new Gson().toJson(body).equals(lastRequestParams)) {
            L.e("拦截请求");
            return false;
        }

        if (mContext instanceof BaseActivity) {
            if (isShowLoading
                    && !((BaseActivity) mContext).loadingDialog.isShowing()) {
                ((BaseActivity) mContext).loadingDialog.show();
//                L.e("simpleName1:" + mContext.getClass().getSimpleName());
            }
        } /*else if (mContext instanceof BaseFragmentActivity) {
            if (isShowLoading
                    && !((BaseFragmentActivity) mContext).loadingDialog
                    .isShowing()) {
                ((BaseFragmentActivity) mContext).loadingDialog.show();
            }
        }*/
        lastRequestType = requestType;
        lastRequestParams = new Gson().toJson(body);

        final String url = initUrl(requestType);
        L.d("httpRequest发送:" + url);
        L.e("body:" + lastRequestParams);
        final String key = url + "=" + lastRequestParams;
        if (NetWorkUtils.checkNetConnect(mContext) == NetWorkUtils.Type.NO_NETWORK_CONNECTION) {
            //没有网络取缓存
            String json = ACache.get(mContext).getAsString(key);

            Object obj;
            if (responseType == null) {
                obj = json;
            } else {
                obj = new Gson().fromJson(json, responseType);

            }
            if (obj != null) {
                L.e("获取缓存成功");
                Message msg = Message.obtain();
                msg.what = requestType;
                msg.arg2 = 99;
                msg.obj = obj;
                mHandler.sendMessage(msg);
            } else {
                //没网没缓存
                mHandler.sendEmptyMessage(404);
            }

        } else {
            Callback callback = new Callback() {

                @Override
                public Object parseNetworkResponse(Response response, int id) throws Exception {
                    String result = response.body().string();
                    L.e("result:" + result);
                    Object obj = null;
                    if (StrUtil.isNotEmpty(result)) {
                        if (hasCache) {
                            mACache.put(key, result);
                        }
                        if (responseType != null) {
                            obj = new Gson().fromJson(result, responseType);
                        } else {
                            obj = result;
                        }
                    }
                    return obj;
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    L.e(e.getMessage());
                    //请求失败
                    //没有网络取缓存
                    String json = ACache.get(mContext).getAsString(key);

                    Object obj;
                    if (responseType == null) {
                        obj = json;
                    } else {
                        obj = new Gson().fromJson(json, responseType);
                    }
                    if (obj != null) {
                        L.e("获取缓存成功");
                        Message msg = Message.obtain();
                        msg.what = requestType;
                        msg.arg2 = 99;
                        msg.obj = obj;
                        mHandler.sendMessage(msg);
                    } else {
                        //没网没缓存
                        mHandler.sendEmptyMessage(500);
                    }
                }

                @Override
                public void onResponse(Object response, int id) {
                    Message msg = Message.obtain();
                    msg.what = requestType;
                    msg.obj = response;
                    mHandler.sendMessage(msg);
//                    mHandler.sendMessageDelayed(msg,3000);
                }
            };

            if (Constant.Http.POST == isPost) {
                OkHttpUtils.post().url(url).params(body).build().execute(callback);
            } else if (Constant.Http.POSTSTRING == isPost) {
                OkHttpUtils.postString().url(url).content(lastRequestParams).build().execute(callback);
            } else {
                OkHttpUtils.get().url(url).params(body).build().execute(callback);
            }
        }
        return true;
    }

    /**
     * 发送网络请求
     *
     * @param requestType   请求标示
     * @param body          请求报文
     * @param hasCache      是否需要缓存
     * @param responseType  返回报文对应解析
     * @param isShowLoading 是否显示等等待
     * @param isZip         是否压缩
     */
    public boolean httpRequest(final int requestType, boolean isLowercase, int isPost, final Map
            body, final boolean hasCache, final Type responseType, boolean isShowLoading, boolean isZip) {
        if (body == null) return false;
        Map map = new HashMap<>();
        if (isLowercase) {
            Set<String> keySet = body.keySet();
            for (String key : keySet) {
                map.put(key.toLowerCase(), body.get(key));
            }
        }
        return httpRequest(requestType, isPost, map, hasCache, responseType, isShowLoading, isZip);
    }


    @Deprecated
    public void uploadFile(final int requestType, final Map body, String fileKey, final Map<String, File> fileMap, final Class responseClass, Callback callback) {

        String url = initUrl(requestType);

        PostFormBuilder postFormBuilder = OkHttpUtils.post()
                .url(url)
                .tag(mContext)
                .params(body);
        if (fileMap != null) {
//            postFormBuilder.addFiles(fileKey, fileMap);
//            postFormBuilder.addFile("file",)
            postFormBuilder.files(fileKey, fileMap);
        }
        if (callback == null) {
            postFormBuilder.build().readTimeOut(50000).connTimeOut(50000).writeTimeOut(50000).execute(new Callback() {
                private int mProgress = 0;

                @Override
                public void inProgress(float progress, long total, int id) {
                    int curr_progress = (int) (progress * 100);
                    if (curr_progress > mProgress) {
                        Message msg = Message.obtain();
                        msg.what = requestType;
                        msg.arg1 = curr_progress;
                        msg.arg2 = 100;
                        mHandler.sendMessage(msg);
                        mProgress = curr_progress;
                    }
                    L.e("mProgress:" + mProgress);
                }

                @Override
                public Object parseNetworkResponse(Response response, int id) throws Exception {
                    String result = response.body().string();
                    L.e("result:" + result);
                    Object obj = null;
                    if (StrUtil.isNotEmpty(result)) {
                        if (responseClass != null) {
                            obj = new Gson().fromJson(result, responseClass);
                        } else {
                            obj = result;
                        }
                    }
                    return obj;
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    mHandler.sendEmptyMessage(500);
                }

                @Override
                public void onResponse(Object response, int id) {
                    Message msg = Message.obtain();
                    msg.what = requestType;
                    msg.obj = response;
                    mHandler.sendMessage(msg);
                }
            });
        } else {
            postFormBuilder.build().execute(callback);
        }
    }

    public void uploadFile(final int requestType, final Map body, String fileKey, final Map<String, File> fileMap, final Type responseClass, Callback callback) {

        String url = initUrl(requestType);

        PostFormBuilder postFormBuilder = OkHttpUtils.post()
                .url(url)
                .tag(mContext)
                .params(body);
        if (fileMap != null) {
//            postFormBuilder.addFiles(fileKey, fileMap);
//            postFormBuilder.addFile("file",)
//            postFormBuilder.files(fileKey, fileMap);
            postFormBuilder.files(fileKey, fileMap);
        }
        L.e(new Gson().toJson(body));
        if (callback == null) {
            postFormBuilder.build().readTimeOut(50000).connTimeOut(50000).writeTimeOut(50000).execute(new Callback() {
                private int mProgress = 0;

                @Override
                public void inProgress(float progress, long total, int id) {
                    int curr_progress = (int) (progress * 100);
                    if (curr_progress > mProgress) {
                        Message msg = Message.obtain();
                        msg.what = requestType;
                        msg.arg1 = curr_progress;
                        msg.arg2 = 100;
                        mHandler.sendMessage(msg);
                        mProgress = curr_progress;
                    }
                    L.e("mProgress:" + mProgress);
                }

                @Override
                public Object parseNetworkResponse(Response response, int id) throws Exception {
                    String result = response.body().string();
                    L.e("result:" + result);
                    Object obj = null;
                    if (StrUtil.isNotEmpty(result)) {
                        if (responseClass != null) {
                            obj = new Gson().fromJson(result, responseClass);
                        } else {
                            obj = result;
                        }
                    }
                    return obj;
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    L.e(e.getMessage());
                    mHandler.sendEmptyMessage(500);
                }

                @Override
                public void onResponse(Object response, int id) {
                    Message msg = Message.obtain();
                    msg.what = requestType;
                    msg.obj = response;
                    mHandler.sendMessage(msg);
                }
            });
        } else {
            postFormBuilder.build().execute(callback);
        }
    }

    public void downloadFile(final int requestType, final String down_url, String fileName) {
        OkHttpUtils.get()
                .url(down_url)
                .tag(mContext)
                .build()
//                    .connTimeOut(20000)
//                    .readTimeOut(20000)
//                    .writeTimeOut(20000)
                .execute(new FileCallBack(FileUtils.ACCOUNT_DIR, fileName) {

                    private int mProgress = 0;

                    @Override
                    public void onError(Call call, Exception e, int id) {
                        mHandler.sendEmptyMessage(500);
                    }

                    @Override
                    public void onResponse(File response, int id) {
                        L.e(response.getAbsolutePath());
                        // 下载成功
                        Message message = mHandler.obtainMessage();
                        message.what = requestType;
                        message.obj = response;
                        mHandler.sendMessage(message);
                    }

                    @Override
                    public void inProgress(float progress, long total, int id) {
                        L.e("进度" + progress + "/" + total);
                        int curr_progress = (int) (progress * 100);
                        if (curr_progress - mProgress > 0) {
                            Message msg = Message.obtain();
                            msg.what = requestType;
                            msg.arg1 = curr_progress;
                            msg.arg2 = 100;
                            mHandler.sendMessage(msg);
                            mProgress = curr_progress;
                        }
                    }
                });
    }

    public void cancel(Context context) {
        OkHttpUtils.getInstance().cancelTag(context);
    }

    public void cancel() {
        OkHttpUtils.getInstance().cancelTag(mContext);
    }

    /**
     * 初始化请求
     *
     * @param requestType
     * @return
     */
    private String initUrl(int requestType) {
        String url = "";
        switch (requestType) {
            /**
             * 发送验证码
             */
            case Constant.RequestType.SEND_MESSAGE:
                url = Constant.RequestDo.SEND_MESSAGE;
                break;
            /**
             * 查询灌区列表
             */
            case Constant.RequestType.GET_IRRIGATED_LIST:
                url = Constant.RequestDo.GET_IRRIGATED_LIST;
                break;
            /**
             * 登录接口
             */
            case Constant.RequestType.GET_LOGIN_IN:
                url = Constant.RequestDo.GET_LOGIN_IN;
                break;
            /**
             * 控制-删除灌区
             */
            case Constant.RequestType.UPDATE_DELETE_IRRIG:
                url = Constant.RequestDo.UPDATE_DELETE_IRRIG;
                break;
            /**
             * 查询所有地块
             */
            case Constant.RequestType.GET_ALL_LANDS:
                url = Constant.RequestDo.GET_ALL_LANDS;
                break;
            /**
             * 控制-默认区域
             */
            case Constant.RequestType.GET_DEVICES_BY_IRRIGID:
                url = Constant.RequestDo.GET_DEVICES_BY_IRRIGID;
                break;
            /**
             * 控制-新建灌区
             */
            case Constant.RequestType.UPDATE_ADD_IRRIGID:
                url = Constant.RequestDo.UPDATE_ADD_IRRIGID;
                break;
            /**
             * 控制-灌溉计划(修改灌区)
             */
            case Constant.RequestType.UPDATE_IRRIGS_PLAN:
                url = Constant.RequestDo.UPDATE_IRRIGS_PLAN;
                break;
            /**
             * 查询监测-采集设备
             */
            case Constant.RequestType.SELECT_STATE_ALL:
                url = Constant.RequestDo.SELECT_STATE_ALL;
                break;
            /**
             * 首页接口-实时监测数据
             */
            case Constant.RequestType.SELECT_LATEST_STATE:
                url = Constant.RequestDo.SELECT_LATEST_STATE;
                break;
            /**
             * 首页天气
             */
            case Constant.RequestType.GET_TIAN_QI:
                url = Constant.RequestDo.GET_TIAN_QI;
                break;
            /**
             * 首页-设备控制状态
             */
            case Constant.RequestType.SELECT_DEVICE_STATE_NUMBER:
                url = Constant.RequestDo.SELECT_DEVICE_STATE_NUMBER;
                break;
            /**
             * 监测 - 控制设备
             */
            case Constant.RequestType.SELECT_DEVICE_STATE:
                url = Constant.RequestDo.SELECT_DEVICE_STATE;
                break;
            /**
             * 首页-查询监控
             */
            case Constant.RequestType.SELECT_LATEST_STATE_BY_MAC:
                url = Constant.RequestDo.SELECT_LATEST_STATE_BY_MAC;
                break;
            /**
             * 敏捷版-查询监控详情
             */
            case Constant.RequestType.SELECT_STATE_BY_CREATE_TIME:
                url = Constant.RequestDo.SELECT_STATE_BY_CREATE_TIME;
                break;

            /**
             * 展会用-自动灌溉系统
             */
            case Constant.RequestType.BOOTH_MODE:
                url = Constant.RequestDo.BOOTH_MODE;
                break;
        }
        return url;
    }


//    private Interceptor interceptor = new Interceptor() {
//        @Override
//        public Response intercept(Chain chain) throws IOException {
//            Request request = chain.request();
//            if (NetWorkUtils.checkNetConnect(mContext) == NetWorkUtils.Type.NO_NETWORK_CONNECTION) {
//                request = request.newBuilder()
//                        .cacheControl(CacheControl.FORCE_CACHE)
//                        .build();
//                L.e("no network");
//            }
//            Response response = chain.proceed(request);
//
//            if (NetWorkUtils.checkNetConnect(mContext) != NetWorkUtils.Type.NO_NETWORK_CONNECTION) {
//                int maxAge = 1 * 60; // 有网络时 设置缓存超时时间0个小时
//                L.e("has network maxAge=" + maxAge);
//                response.newBuilder()
//                        .header("Cache-Control", "public, max-age=" + maxAge)
//                        .removeHeader("Pragma")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
//                        .build();
//            } else {
//                L.e("network error");
//                int maxStale = 60 * 60 * 24 * 28; // 无网络时，设置超时为4周
//                L.e("has maxStale=" + maxStale);
//                response.newBuilder()
//                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
//                        .removeHeader("Pragma")
//                        .build();
//                L.e("response build maxStale=" + maxStale);
//            }
//            return response;
//        }
//    };

}

